package com.brainshare.system.service.impl;

import com.brainshare.an.domain.AnWechatUser;
import com.brainshare.an.domain.AnWechatUserMechanism;
import com.brainshare.an.service.IAnWechatUserMechanismService;
import com.brainshare.an.service.IAnWechatUserService;
import com.brainshare.common.constant.Constants;
import com.brainshare.common.constant.NumberConstants;
import com.brainshare.common.enums.*;
import com.brainshare.common.utils.DateUtils;
import com.brainshare.common.utils.NumberUtils;
import com.brainshare.common.utils.StringUtils;
import com.brainshare.system.domain.RedPacketRecord;
import com.brainshare.system.domain.SysBuriedPoint;
import com.brainshare.system.domain.SysBuriedPointResult;
import com.brainshare.system.domain.query.BuriedPointQuery;
import com.brainshare.system.domain.vo.LoginDetailVO;
import com.brainshare.system.domain.vo.LoginSumVO;
import com.brainshare.system.domain.vo.StatisticsAnDetailVO;
import com.brainshare.system.domain.vo.StatisticsShareDetailVO;
import com.brainshare.system.mapper.SysBuriedPointMapper;
import com.brainshare.system.mapper.SysBuriedPointResultMapper;
import com.brainshare.system.service.IRedPacketRecordService;
import com.brainshare.system.service.ISysBuriedPointResultService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 埋点结果Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-08-25
 */
@Service
public class SysBuriedPointResultServiceImpl implements ISysBuriedPointResultService 
{
    /**
     * 日志
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private SysBuriedPointResultMapper sysBuriedPointResultMapper;
    @Autowired
    private SysBuriedPointMapper sysBuriedPointMapper;
    @Autowired
    private IAnWechatUserService anWechatUserService;
    @Autowired
    private IRedPacketRecordService redPacketRecordService;
    @Autowired
    IAnWechatUserMechanismService anWechatUserMechanismService;
    /**
     * 查询埋点结果
     * 
     * @param id 埋点结果主键
     * @return 埋点结果
     */
    @Override
    public SysBuriedPointResult selectSysBuriedPointResultById(Long id)
    {
        return sysBuriedPointResultMapper.selectSysBuriedPointResultById(id);
    }

    @Override
    public LoginSumVO getLoginSum(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        return sysBuriedPointResultMapper.getLoginSum(buriedPointQuery);
    }

    @Override
    public List<LoginDetailVO> getLoginDetailList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        return sysBuriedPointResultMapper.getLoginDetailList(buriedPointQuery);
    }

    @Override
    public Long getAnCompleteSum(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        Long anCompleteSum = sysBuriedPointResultMapper.getAnCompleteSum(buriedPointQuery);
        return null==anCompleteSum?NumberConstants.ZERO:anCompleteSum;
    }

    @Override
    public List<StatisticsAnDetailVO> getAnDetailList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        return sysBuriedPointResultMapper.getAnDetailList(buriedPointQuery);
    }

    @Override
    public Long getShareSum(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        Long shareSum = sysBuriedPointResultMapper.getShareSum(buriedPointQuery);
        return null==shareSum?NumberConstants.ZERO:shareSum;
    }

    @Override
    public List<StatisticsShareDetailVO> getShareDetailList(BuriedPointQuery buriedPointQuery) {
        BuriedPointQuery.checkParam(buriedPointQuery);
        BuriedPointQuery.handleParam(buriedPointQuery);
        return sysBuriedPointResultMapper.getShareDetailList(buriedPointQuery);
    }

    @Override
    public List<StatisticsShareDetailVO> getShareDetailList(List<StatisticsShareDetailVO> statisticsShareDetailVOList) {
        if (CollectionUtils.isEmpty(statisticsShareDetailVOList)){
            return null;
        }
        for (StatisticsShareDetailVO shareDetailVO : statisticsShareDetailVOList) {
            shareDetailVO.setShareAmount(NumberUtils.getYuanValue(shareDetailVO.getLongShareAmount()));
        }
        return statisticsShareDetailVOList;
    }

    /**
     * 查询埋点结果列表
     * 
     * @param sysBuriedPointResult 埋点结果
     * @return 埋点结果
     */
    @Override
    public List<SysBuriedPointResult> selectSysBuriedPointResultList(SysBuriedPointResult sysBuriedPointResult)
    {
        return sysBuriedPointResultMapper.selectSysBuriedPointResultList(sysBuriedPointResult);
    }

    @Override
    public void addBuriedPointResult(String date) {
        long ts = DateUtils.getTimeMillis();
        try{
            logger.info("{},新增埋点统计结果开始,日期{}", ts, date);
            SysBuriedPoint sysBuriedPointParam = new SysBuriedPoint();
            sysBuriedPointParam.setCreateDate(date);
            List<SysBuriedPoint> sysBuriedPointList = sysBuriedPointMapper.getSysBuriedPointListByDate(sysBuriedPointParam);
            if (CollectionUtils.isEmpty(sysBuriedPointList)) {
                logger.info("{}，日期{}不存在埋点数据", ts, date);
                return;
            }

            List<SysBuriedPointResult> sysBuriedPointResultList = new ArrayList<>();
            //List<SysBuriedPoint> distinctSysBuriedPointList = sysBuriedPointList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getCustomerId() + ";" + o.getPhone()))), ArrayList::new));
            for (SysBuriedPoint sysBuriedPoint : sysBuriedPointList) {

                sysBuriedPointParam = new SysBuriedPoint();
                sysBuriedPointParam.setCustomerId(sysBuriedPoint.getCustomerId());
                sysBuriedPointParam.setCreateDate(date);
                List<SysBuriedPoint> pointList = sysBuriedPointMapper.selectSysBuriedPointList(sysBuriedPointParam);

                SysBuriedPointResult sysBuriedPointResult = new SysBuriedPointResult();
                sysBuriedPointResult.setDate(date);
                Long customerId = sysBuriedPoint.getCustomerId();
                customerId = null == customerId ? NumberConstants.NEGATIVE_ONE : customerId;
                sysBuriedPointResult.setUserId(customerId);
                sysBuriedPointResult.setPhone(sysBuriedPoint.getPhone());
                //注册
                // 是否新用户
                Integer newFlag = getIsNew(ts,sysBuriedPoint.getPhone(),date);
                sysBuriedPointResult.setIsNew(newFlag);
                // 进入详情页次数
                long detailCount = pointList.stream().filter(item ->
                        item.getSection().equals(String.valueOf(BuriedPointPathEnum.LINK_CARD_LINK_SHARE.getSectionCode())) &&
                                item.getModule().equals(String.valueOf(BuriedPointPathEnum.LINK_CARD_LINK_SHARE.getModuleCode())) &&
                                item.getFunction().equals(String.valueOf(BuriedPointPathEnum.LINK_CARD_LINK_SHARE.getFunctionCode()))
                ).count();
                sysBuriedPointResult.setEnterDetailPageCount(detailCount);
                // 登陆次数
                long loginCount = pointList.stream().filter(item ->
                        item.getSection().equals(String.valueOf(BuriedPointPathEnum.LOGIN_LOGIN_SUCCESS.getSectionCode())) &&
                                item.getModule().equals(String.valueOf(BuriedPointPathEnum.LOGIN_LOGIN_SUCCESS.getModuleCode())) &&
                                item.getFunction().equals(String.valueOf(BuriedPointPathEnum.LOGIN_LOGIN_SUCCESS.getFunctionCode()))
                ).count();
                sysBuriedPointResult.setLoginCount(loginCount);
                if (null != sysBuriedPoint.getCustomerId()) {
                    //筛查
                    AnWechatUserMechanism anWechatUserMechanism = new AnWechatUserMechanism();
                    anWechatUserMechanism.setWechatUserId(sysBuriedPoint.getCustomerId());
                    List<AnWechatUserMechanism> anWechatUserMechanismList = anWechatUserMechanismService.selectAnWechatUserMechanismList(anWechatUserMechanism);
                    List<AnWechatUserMechanism> mechanismList = anWechatUserMechanismList.stream().filter(item -> isSameDate(item.getScreeningDoneTime(), date)).collect(Collectors.toList());
                    Integer anCompletedFlag = CollectionUtils.isEmpty(mechanismList) ? YNEnum.NO.getCode() : YNEnum.YES.getCode();
                    sysBuriedPointResult.setAnCompletedFlag(anCompletedFlag);

                    sysBuriedPointParam = new SysBuriedPoint();
                    sysBuriedPointParam.setCustomerId(sysBuriedPoint.getCustomerId());
                    sysBuriedPointParam.setAnEntranceFlag(YNEnum.YES.getCode());
                    List<SysBuriedPoint> buriedPointList = sysBuriedPointMapper.selectSysBuriedPointList(sysBuriedPointParam);
                    String anEntrance = StringUtils.EMPTY;
                    if (!CollectionUtils.isEmpty(buriedPointList)) {
                        SysBuriedPoint point = buriedPointList.stream().sorted(Comparator.comparing(SysBuriedPoint::getCreateDate).reversed()).findFirst().orElseGet(null);
                        if (null == point || null == point.getSection() || null == point.getModule() || null == point.getFunction()) {
                            logger.info("ts:{} ，未找到筛查入口，或筛查入口字段值不正确", ts, point);
                        } else {
                            anEntrance = AnEntranceEnum.getEntranceByPath(Integer.valueOf(point.getSection()), Integer.valueOf(point.getModule()), Integer.valueOf(point.getFunction()));
                        }
                    }
                    sysBuriedPointResult.setAnEntrance(anEntrance);
                    //分享
                    RedPacketRecord redPacketRecord = new RedPacketRecord();
                    redPacketRecord.setUserId(sysBuriedPoint.getCustomerId());
                    redPacketRecord.setRedPacketType(RedPacketTypeEnum.RED_PACKET.getCode());
                    redPacketRecord.setRedPacketType2(RedPacketType2Enum.SHARE.getCode());
                    List<RedPacketRecord> redPacketRecordList = redPacketRecordService.selectRedPacketRecordList(redPacketRecord);
                    int shareTime = CollectionUtils.isEmpty(redPacketRecordList) ? 0 : redPacketRecordList.size();
                    sysBuriedPointResult.setShareTime(shareTime);
                    List<RedPacketRecord> recordList = redPacketRecordList.stream().filter(item -> item.getRedPacketStatus().equals(RedPacketStatusEnum.RECEIVED.getCode())).collect(Collectors.toList());
                    long shareAmount = recordList.stream().mapToLong(RedPacketRecord::getRedPacketAmount).sum();
                    sysBuriedPointResult.setShareAmount(shareAmount);
                }else{
                    sysBuriedPointResult.setAnEntrance("");
                    sysBuriedPointResult.setAnCompletedFlag(YNEnum.NO.getCode());
                    sysBuriedPointResult.setShareTime(NumberConstants.ZERO);
                    sysBuriedPointResult.setShareAmount(Long.valueOf(NumberConstants.ZERO));
                }
                sysBuriedPointResult.setYn(YNEnum.NO.getCode());
                Date nowDate = DateUtils.getNowDate();
                sysBuriedPointResult.setCreateUser(Constants.USER_TIMER);
                sysBuriedPointResult.setCreateTime(nowDate);
                sysBuriedPointResult.setUpdateUser(Constants.USER_TIMER);
                sysBuriedPointResult.setUpdateTime(nowDate);

                sysBuriedPointResultList.add(sysBuriedPointResult);
                if (sysBuriedPointResultList.size() == NumberConstants.TEN) {
                    int i = sysBuriedPointResultMapper.batchInsertSysBuriedPointResult(sysBuriedPointResultList);
                    logger.info("ts:{}，批量新增结果{}", ts, i);
                    sysBuriedPointResultList.clear();
                }
                //sysBuriedPointResultMapper.insertSysBuriedPointResult(sysBuriedPointResult);
            }
            int i = sysBuriedPointResultMapper.batchInsertSysBuriedPointResult(sysBuriedPointResultList);
            logger.info("ts:{}，批量新增结果{}",ts,i);
            sysBuriedPointResultList.clear();
        }catch (Exception e){
            logger.warn("ts:{}，新增埋点结果异常",ts,e);
        }
    }

    private boolean isSameDate(Date date1,String date2)
    {
        if (null==date1||StringUtils.isBlank(date2)){
            return false;
        }
        //Date date = DateUtils.parseDate(date1);
        String strDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date1);
        return strDate.equals(date2);
    }


    private Integer getIsNew(Long ts,String phone, String date) {
        AnWechatUser anWechatUser = new AnWechatUser();
        anWechatUser.setPhone(phone);
        List<AnWechatUser> anWechatUserList = anWechatUserService.selectAnWechatUserList(anWechatUser);
        if (CollectionUtils.isEmpty(anWechatUserList)) {
            logger.warn("ts:{}，用户{}不存在",ts, phone);
        }
        boolean result = isSameDate(anWechatUserList.get(0).getCreateTime(), date);
        return result ? YNEnum.YES.getCode() : YNEnum.NO.getCode();
    }

    /**
     * 新增埋点结果
     * 
     * @param sysBuriedPointResult 埋点结果
     * @return 结果
     */
    @Override
    public int insertSysBuriedPointResult(SysBuriedPointResult sysBuriedPointResult)
    {
        sysBuriedPointResult.setCreateTime(DateUtils.getNowDate());
        return sysBuriedPointResultMapper.insertSysBuriedPointResult(sysBuriedPointResult);
    }

    /**
     * 修改埋点结果
     * 
     * @param sysBuriedPointResult 埋点结果
     * @return 结果
     */
    @Override
    public int updateSysBuriedPointResult(SysBuriedPointResult sysBuriedPointResult)
    {
        sysBuriedPointResult.setUpdateTime(DateUtils.getNowDate());
        return sysBuriedPointResultMapper.updateSysBuriedPointResult(sysBuriedPointResult);
    }

    /**
     * 批量删除埋点结果
     * 
     * @param ids 需要删除的埋点结果主键
     * @return 结果
     */
    @Override
    public int deleteSysBuriedPointResultByIds(Long[] ids)
    {
        return sysBuriedPointResultMapper.deleteSysBuriedPointResultByIds(ids);
    }

    /**
     * 删除埋点结果信息
     * 
     * @param id 埋点结果主键
     * @return 结果
     */
    @Override
    public int deleteSysBuriedPointResultById(Long id)
    {
        return sysBuriedPointResultMapper.deleteSysBuriedPointResultById(id);
    }
}
